﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Interop;

/*WINDOWS USING KEYBOARD MUST DO THE FOLLOWING TO WORK PROPERLY:
 * 
 * 1: ALL CONTROLS NEED TO BIND TO FOCUS EVENT:
 * private void focusHandler(object sender, RoutedEventArgs e)
        {
            if (sender is TextBox) //show keyboard and bind
            {
                theKeyboard.bindToControl((TextBox)sender);
                theKeyboard.show();
            }
            else if (sender is OnScreenKeyboard) // special do nothing case...focus is getting bounced around between the keyboard and bound control
            {

            }
            else //hide keyboard (clicked button or window or something)
            {
                theKeyboard.clearControlBinding();
                theKeyboard.hide();
            }
        }
 * 
 * 2. WINDOWS NEED TO LEFT_MOUSEBUTTONCLICK BIND TO:
 * 
        private void windowLeftMouseButtonUp(object sender, MouseButtonEventArgs e)
        {
            theKeyboard.clearControlBinding();
            theKeyboard.hide();
            //best to set focus to some button here
        }
 * */

namespace Kiosk
{
    /// <summary>
    /// Interaction logic for OnScreenKeyboard.xaml
    /// </summary>
    public partial class OnScreenKeyboard : UserControl
    {
        private object boundControlHolder = null;
        private Boolean shiftClicked = false;
        private Boolean capslockClicked = false;
        LinearGradientBrush defaultBrush = new LinearGradientBrush();
        GradientStop gc1 = new GradientStop(Color.FromArgb(255, 248, 248, 248), 0.0);
        GradientStop gc2 = new GradientStop(Color.FromArgb(255, 209, 207, 207), 1.0);


        public OnScreenKeyboard()
        {
            InitializeComponent();
            this.hide();
            DataContext = this;
            defaultBrush.GradientStops.Add(gc1);
            defaultBrush.GradientStops.Add(gc2);
            defaultBrush.StartPoint = new Point(0.5, 0.0);
            defaultBrush.EndPoint = new Point(0.5, 1.0);
        }

        private void ClickHandler(object sender, RoutedEventArgs e)
        {
            Button clickedButton = sender as Button;
            if (clickedButton != null)
            {
                if (boundControlHolder != null)
                {
                    //maintain expected focus and index
                    if (boundControlHolder is TextBox)
                    {
                        TextBox boundControl = (TextBox)boundControlHolder;

                        int insertIndex = boundControl.CaretIndex;

                        switch ((string)clickedButton.Content)
                        {
                            case "Tab":                                
                                if (Application.Current.Windows.OfType<KioskLogin>().FirstOrDefault(w => w.IsActive) == null)
                                {
                                    boundControl.Text = boundControl.Text.Insert(boundControl.CaretIndex, "\t");
                                }
                                else
                                {
                                    //TODO: Somehow get the tab button to move to the next tab index
                                }
                                break;
                            case "Backspace":
                                if (boundControl.Text.Length > 0)
                                {
                                    boundControl.Text = boundControl.Text.Substring(0, boundControl.Text.Length - 1);
                                }
                                break;
                            case "Enter":                                
                                if (Application.Current.Windows.OfType<KioskLogin>().FirstOrDefault(w => w.IsActive) == null)
                                {
                                    boundControl.Text = boundControl.Text.Insert(boundControl.CaretIndex, "\n");
                                }
                                else
                                {
                                    Application.Current.Windows.OfType<KioskLogin>().FirstOrDefault().btnLogin.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                                }
                                break;
                            case " ":
                                boundControl.Text = boundControl.Text.Insert(boundControl.CaretIndex, clickedButton.Content.ToString());
                                break;
                            case "Shift":
                                this.toggleShift();
                                break;
                            case "Caps Lock":
                                this.toggleCaps();
                                break;

                            default:
                                if (shiftClicked)
                                {
                                    boundControl.Text = boundControl.Text.Insert(boundControl.CaretIndex, clickedButton.Content.ToString());
                                    this.toggleShift();
                                }
                                else
                                {
                                    if (capslockClicked)
                                    {
                                        boundControl.Text = boundControl.Text.Insert(boundControl.CaretIndex, clickedButton.Content.ToString());
                                    }
                                    else
                                    {
                                        boundControl.Text = boundControl.Text.Insert(boundControl.CaretIndex, clickedButton.Content.ToString().ToLower());
                                    }
                                }
                                break;
                        }
                        boundControl.Focus();
                        boundControl.CaretIndex = insertIndex + 1;
                    }
                    else if (boundControlHolder is PasswordBox)
                    {
                        PasswordBox boundControl = (PasswordBox)boundControlHolder;

                        int insertIndex = boundControl.Password.Length;

                        switch ((string)clickedButton.Content)
                        {
                            case "Tab":
                                if (Application.Current.Windows.OfType<KioskLogin>().FirstOrDefault(w => w.IsActive) == null)
                                {
                                    boundControl.Password = boundControl.Password.Insert(insertIndex, "\t");
                                }
                                else
                                {
                                    //TODO: Cause a tab to be pressed
                                }
                                break;
                            case "Backspace":
                                if (boundControl.Password.Length > 0)
                                {
                                    boundControl.Password = boundControl.Password.Substring(0, boundControl.Password.Length - 1);
                                }
                                break;
                            case "Enter":
                                if (Application.Current.Windows.OfType<KioskLogin>().FirstOrDefault(w => w.IsActive) != null)
                                {
                                    Application.Current.Windows.OfType<KioskLogin>().FirstOrDefault().btnLogin.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));                                    
                                }
                                else if(Application.Current.Windows.OfType<PasswordPrompt>().FirstOrDefault(w => w.IsActive) != null)
                                {
                                    Application.Current.Windows.OfType<PasswordPrompt>().FirstOrDefault().btnSubmit.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
                                }
                                else
                                {
                                    boundControl.Password = boundControl.Password.Insert(insertIndex, "\n");
                                }
                                break;
                            case " ":
                                boundControl.Password = String.Format("{0}{1}", boundControl.Password.ToString(), clickedButton.Content.ToString());
                                break;
                            case "Shift":
                                this.toggleShift();
                                break;
                            case "Caps Lock":
                                this.toggleCaps();
                                break;

                            default:
                                if (shiftClicked)
                                {
                                    boundControl.Password = String.Format("{0}{1}", boundControl.Password.ToString(), clickedButton.Content.ToString());
                                    this.toggleShift();
                                }
                                else
                                {
                                    if (capslockClicked)
                                    {
                                        boundControl.Password = String.Format("{0}{1}", boundControl.Password.ToString(), clickedButton.Content.ToString());
                                    }
                                    else
                                    {
                                        boundControl.Password = String.Format("{0}{1}", boundControl.Password.ToString(), clickedButton.Content.ToString().ToLower());
                                    }
                                }
                                break;
                        }
                    }                    
                    else
                    {
                        return;
                    }

                }
            }
        }       

        private void toggleShift()
        {
            if (shiftClicked)
            {
                //TODO: Make sure the color goes back to the proper brush
                shiftClicked = false;     
                lShift.Background = defaultBrush;
                rShift.Background = defaultBrush;
            }
            else
            {
                shiftClicked = true;
                lShift.Background = new SolidColorBrush(Colors.Blue);
                rShift.Background = new SolidColorBrush(Colors.Blue);
            }
        }

        private void toggleCaps()
        {
            if (capslockClicked)
            {
                //TODO: Make sure the color goes back to the proper brush
                capslockClicked = false;
                KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.CapsLock);
                args.RoutedEvent = Keyboard.KeyDownEvent;
                InputManager.Current.ProcessInput(args);
                capsLock.Background = defaultBrush;
            }
            else
            {
                capslockClicked = true;
                KeyEventArgs args = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.CapsLock);
                args.RoutedEvent = Keyboard.KeyDownEvent;
                InputManager.Current.ProcessInput(args);
                capsLock.Background = new SolidColorBrush(Colors.Blue);
            }
        }

        public void hide()
        {
            this.Visibility = System.Windows.Visibility.Hidden;
        }

        public void show()
        {
            this.Visibility = System.Windows.Visibility.Visible;
        }

        public void bindToControl(object sender)
        {
            this.boundControlHolder = sender;
        }

        public void clearControlBinding()
        {
            boundControlHolder = null;
        }

        private void CloseKeyboard_Click(object sender, RoutedEventArgs e)
        {
            this.hide();
        }
    }
}
